/*
 * Copyright (c) 2021. $date$
 */

package com.mhy.dexload;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;

import static com.mhy.dexload.DexUtils.APP_DEX;

public class MainActivity extends AppCompatActivity {
    private  String dexDir;
    private boolean hasES() {//是否有外部存储
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    public File getCacheDirs() {
        File cache;
        if (hasES()) {
            cache = getExternalCacheDir();
        } else {
            cache = getCacheDir();
        }
        if (!cache.exists()) {
            cache.mkdirs();
        }
        return cache;
    }

    private void copyFile(final String fileName) {
        //无需权限 getExternalFilesDir(null) , getDir() data/data/xxx/
        final File file = new File(dexDir);
        //可以 外部
//        File file = new File(getExternalFilesDir(null).getPath() + File.separator + fileName);
        String md5 = Md5Utils.getFileMD5(file, 16);
        Log.d("mhyLog", md5);
        if (file.exists() && "04a9eaf477313a588041497ec16909c5".equals(md5)) {
            //已存在的和 将获取的一致 不再重复
        } else {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        InputStream inputStream = getAssets().open(fileName);
                        OutputStream outputStream = new FileOutputStream(file);
                        byte[] buffer = new byte[1444];
                        int readSize;
                        while ((readSize = inputStream.read(buffer)) != 0) {
                            outputStream.write(buffer, 0, readSize);
                        }
                        inputStream.close();
                        outputStream.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            thread.start();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //dexDir 可以是外部路径
        dexDir=getDir(APP_DEX,Context.MODE_PRIVATE).getAbsolutePath()+ File.separator + "string.dex";
       // dexDir=getExternalFilesDir(null).getPath() + File.separator + "string.dex";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 一次请求多个权限[], 如果其他有权限是已经授予的将会自动忽略掉
            if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 101);
            } else {
                copyFile("string.dex");
            }
        } else {
            copyFile("string.dex");
        }
        Log.e("mhyLog",getPackageName());
    }

    /**
     * //        Environment.getExternalStorageDirectory().getAbsolutePath()//sdcard
     * //        getExternalFilesDir(null) sdcard/Android/data/packagename/file
     */
   private final String className="com.mhy.plugin.ShowString";
   private final String mothodName="sayString";
    private void loadDex() {

        DexUtils dexUtils = new DexUtils(this);
        String showString = (String) dexUtils.loadPlugin(dexDir, className, mothodName, new Class<?>[0], new Object[0]);
        //上面 调用的方法 String sayString()
        if (showString != null) {
            //通过接口实现调用方法
            ((Button) findViewById(R.id.main_btn)).setText(showString);
            dexUtils.loadPlugin(dexDir, className, mothodName, new Class<?>[]{Context.class, String.class}, new Object[]{MainActivity.this, "dexload你说啥就是啥"});
            //上面 调用的方法 void sayString(Context,String)
        }
        dexUtils.showClassLoader();
    }
    private void hotFix() {
        // 加载类 全名
        try {
            Hotfix.patch(this,/*getPackageName(),*/dexDir, className);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        try {
            Class<?> mClass = Class.forName(className);
            Method method = mClass.getMethod(mothodName, Context.class, String.class);//获取方法和参数类型
            method.setAccessible(true);
            //创建dynamic实例
            method.invoke(mClass.newInstance(), MainActivity.this, "hotfix你说啥就是啥");//调用参数 传参
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            if (requestCode == 100) {
                loadDex();
            }
            if (requestCode == 101) {
                copyFile("string.dex");
            }
        }
    }

    public void loadDex(View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 一次请求多个权限[], 如果其他有权限是已经授予的将会自动忽略掉
            if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
            } else {
                loadDex();
            }
        } else {
            loadDex();
        }
    }
}